<template>
  <view class="" @click="onTap">
    <button
      class="but"
      :id="id"
      :class="ggclass"
      :data-id="dId"
      :style="[styles]"
      @touchstart="touchstart"
      @touchend="touchend"
      :open-type="openType"
    >
      <c-loading
        v-if="loading"
        :loading="loading"
        size="30rpx"
        style="margin-right: 10rpx"
      ></c-loading>
      <slot></slot>
    </button>
  </view>
</template>

<script setup lang="ts">
import { ref, defineProps, reactive, computed, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance() as any;
let timeout: number | null = null;
import { colorLuminance } from "../ways/color.js";

const props = defineProps({
  fontSize: {
    type: String,
    default: "",
  },
  loading: {
    type: Boolean,
    default: false,
  },
  width: {
    type: String,
    default: "",
  },
  height: {
    type: String,
    default: "",
  },
  ggclass: {
    type: String,
    default: "",
  },
  delayed: {
    type: Number,
    default: 200,
  },
  color: {
    type: String,
    default: "",
  },
  background: {
    type: String,
    default: "main",
  },
  boxShadow: {
    type: String,
    default: "",
  },
  radius: {
    type: String,
    default: "",
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  border: {
    type: String,
    default: "",
  },
  padding: {
    type: String,
    default: "",
  },
  isOpenPattern: {
    type: Boolean,
    default: false,
  },
  openType: {
    type: String,
    default: "",
  },
  id: {
    type: String,
    default: "",
  },
  dId: {
    type: String,
    default: "",
  },
});
const state = reactive({
  oldBackground: "",
  oldColor: "",
});

const styles = computed(() => {
  let params = {
    background: backs.value,
    width: proxy.$rpxunit(props.width),
    height: proxy.$rpxunit(props.height),
    borderRadius: proxy.$rpxunit(borderRadius.value),
    padding: props.padding
      .split(" ")
      .map((v) => proxy.$rpxunit(v))
      .join(" "),
    color: colors.value,
    boxShadow: props.boxShadow,
    fontSizes: proxy.$rpxunit(fontSizes.value),
    border: props.border,
  };
  return params;
});
const fontSizes = computed(() => {
  return props.fontSize || proxy.$btnStyle.fontSize;
});
const borderRadius = computed(() => {
  return props.radius || proxy.$btnStyle.radius;
});
const colors = computed({
  get() {
    if (props.disabled) return "#D0D0D0";
    if (state.oldColor) {
      return state.oldColor;
    } else {
      return (
        proxy.$color[props.color] ||
        props.color ||
        proxy.$btnStyle.color ||
        "#FFF"
      );
    }
  },
  set(val) {
    return (state.oldColor = val);
  },
});
let backs = computed({
  get() {
    // if (this.disabled) return this.colorLuminance(this.$color[this.background] || this.background, -0.2)
    if (props.disabled) return colorLuminance("#D0D0D0", 0.8);
    if (state.oldBackground) {
      return state.oldBackground;
    } else {
      return (
        proxy.$color[props.background] ||
        props.background ||
        proxy.$btnStyle.background ||
        "#D0D0D0"
      );
    }
  },
  set(val) {
    state.oldBackground = val;
  },
});
const touchstartBack = computed(() => {
  return colorLuminance(backs.value, 0.4);
});
const touchestartColor = computed(() => {
  return colorLuminance(colors.value, 0.4);
});

// 手指按下
const touchstart = (e: TouchEvent) => {
  backs.value = touchstartBack.value;
  colors.value = touchestartColor.value;
  proxy.$emit("touchstart", e);
};
// 手指松开
const touchend = (e: TouchEvent) => {
  backs.value = proxy.$color[props.background] || props.background;
  colors.value = proxy.$color[props.color] || props.color;
  proxy.$emit("touchend", e);
};
const onTap = (event: Event) => {
  if (props.loading) return;
  if (props.disabled) return;
  debounce(() => {
    proxy.$emit("click", event);
  }, props.delayed);
};

/**
 * 防抖原理：一定时间内，只有最后一次操作，再过wait毫秒后才执行函数
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
const debounce = (
  func: Function,
  wait: number = 500,
  immediate: boolean = true
) => {
  if (timeout !== null) clearTimeout(timeout);
  // 建议按钮使用立即执行，输入框使用延时执行
  if (immediate) {
    const callNow = !timeout;
    timeout = setTimeout(() => {
      timeout = null;
    }, wait);
    if (callNow) typeof func === "function" && func();
  } else {
    timeout = setTimeout(() => {
      typeof func === "function" && func();
    }, wait);
  }
};
</script>

<style lang="scss" scoped>
.but {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  padding: 20rpx 25rpx;
  height: 80rpx;
  user-select: none;
  font-size: 30rpx;
  box-sizing: border-box;
  border-radius: 20rpx;

  &::after {
    border: none;
  }
}
</style>